package com.game.majiang.logic.chexuan;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;

import com.game.majiang.algorithm.PaperCard;
import com.game.majiang.algorithm.chexuan.GameAlgorithm;
import com.game.majiang.algorithm.chexuan.GamePlayerInfo;
import com.game.majiang.config.ChexuanStructrue;
import com.game.majiang.config.DataManager;
import com.game.majiang.config.LogManager;
import com.game.majiang.logic.LogicClient;
import com.game.majiang.logic.LogicPlayer;
import com.game.majiang.logic.LogicServer;
import com.game.majiang.logic.LogicTable;
import com.game.majiang.vo.GrateCardsVo;
import com.game.majiang.vo.UserVo;
import com.game.server.db.dao.GamelogDao;
import com.game.server.db.dao.UsersDao;
import com.game.server.db.entity.Gamelog;
import com.game.server.db.entity.XyClubInfo;
import com.game.server.message.proto.out.BroadcastCanOperationRsp;
import com.game.server.message.proto.out.BroadcastOperationRsp;
import com.game.server.message.proto.out.BroadcastSetupbobo;
import com.game.server.message.proto.out.BroadcastZuPaiRsp;
import com.game.server.message.proto.out.ControlBringInRsp;
import com.game.server.message.proto.out.ControlBringInStruct;
import com.game.server.message.proto.out.GameEndRsp;
import com.game.server.message.proto.out.GameReviewStructrue;
import com.game.server.message.proto.out.GameStartRsp;
import com.game.server.message.proto.out.GameStartStructrue;
import com.game.server.message.proto.out.GetControlBringInDataRsp;
import com.game.server.message.proto.out.LeaveRsp;
import com.game.server.message.proto.out.LicensingRsp;
import com.game.server.message.proto.out.LicensingStructure;
import com.game.server.message.proto.out.NoticeCuopaiEndRsp;
import com.game.server.message.proto.out.NoticeCuopaiRsp;
import com.game.server.message.proto.out.OperationRsp;
import com.game.server.message.proto.out.OtherEnterRsp;
import com.game.server.message.proto.out.OtherLeaveRoom;
import com.game.server.message.proto.out.PlayerCuopaiNoticeRsp;
import com.game.server.message.proto.out.PlayerInfo;
import com.game.server.message.proto.out.RealTimeRecordStructrue;
import com.game.server.message.proto.out.RoomInfoRsp;
import com.game.server.message.proto.out.SettlementRsp;
import com.game.server.message.proto.out.SettlementStructrue;
import com.game.server.message.proto.out.SetupboboRsp;
import com.game.server.message.proto.out.SummaryCalculationRsp;
import com.game.server.message.proto.out.ZuPaiRsp;
import com.game.server.system.AbstractPlayer;
import com.game.server.system.AbstractRoom;

import com.game.server.util.CompuUtils;
import com.game.server.web.WebServer;
import com.robot.RobotClient;
import com.robot.RobotManager;
import com.timing.RobotTask;

import lombok.Getter;
import lombok.ToString;

@ToString
public class ChexuanTabale extends LogicTable {


  private int round = 0;//游戏回合
  private int gameReadyTime = 0;//准备倒计时
  private int licensingTime = 0;//发牌延时通知谁操作
  private int zhifaLicensingToGroupCardsBoolTime = 0;//直发牌到组牌延时
  private int gameStartMangguoStopTime = 0;//有芒果 游戏开始停止时间
  private int gameEndToNextStartTime = 0;//游戏结束到下一把开始
  private ArrayList<ArrayList<PaperCard>> paperCardLibrary = new ArrayList<ArrayList<PaperCard>>();
  @Getter
  private int maxBet = 0;//桌子最大压
  @Getter
  private boolean currRoundBetBool = false;//当前压注
  private int pichi = 0;//皮池
  @Getter
  private int mangguochi = 0;//芒果池
  private int mangguoCount = 0;//芒果次数
  private int mangguoType = 0;//1休芒 2揍芒
  private int zouMangUid = 0;//揍芒 不用出芒


  @Getter
  private HashMap<Integer, ArrayList<GameReviewStructrue>> mapGameReview = new HashMap<Integer, ArrayList<GameReviewStructrue>>();//牌局回顾
  @Getter
  private HashMap<Integer, HashSet<Integer>> mapGameReviewXiupaiUids = new HashMap<Integer, HashSet<Integer>>();//牌局回顾 秀牌用户
  @Getter
  private HashMap<Integer, ControlBringInStruct> mapCBI = new HashMap<Integer, ControlBringInStruct>();//控制带入 未处理记录

  private int cbiId = 0;//控制带入记录id

  public ChexuanTabale(int id) {
    super(id);
    this.watchWar = new ChexuanWatchWar(id);
  }


  private void gameStart() {
    if (this.chexuanStatus != ChexuanTableStatus.READ || this.gameEnd) {
      return;
    }
    int gameCount = 0;
    for (AbstractPlayer abPlayer : getPlayers()) {
      ChexuanPlayer tempPlayer = (ChexuanPlayer) abPlayer;
      if (tempPlayer.isReady()) {
        gameCount++;
        tempPlayer.setLiuZuoEndTime(0);
        tempPlayer.setSetBoboTime(0);
      }
    }
    if (gameCount > 1) {
      updateStatus(ChexuanTableStatus.LICENSING);
      ArrayList<GameStartStructrue> listGSS = new ArrayList<GameStartStructrue>();
      ChexuanStructrue struct = (ChexuanStructrue) this.create;
      if (struct.getKaiqimangquan() == 1) {
        if (this.mangguoCount == 0) {
          this.mangguoCount = 1;
        }
        if (this.mangguoType == 0) {
          this.mangguoType = 1;
        }
      }
      LogManager.getInstance().Log("开局有芒果：" + this.mangguochi + " tableid:" + getID());
      int mangguoFen = 0;
      if (this.mangguoType != 0) {
        mangguoFen = this.create.getDifen() * this.mangguoCount * 2;
      }
      for (AbstractPlayer abPlayer : getPlayers()) {
        ChexuanPlayer tempPlayer = (ChexuanPlayer) abPlayer;
        if (tempPlayer.isReady()) {
          tempPlayer.setGameStartMoney(tempPlayer.getUsebobo());
          this.pichi += this.create.getDifen();
          tempPlayer.setUsebobo(tempPlayer.getUsebobo() - this.create.getDifen());
          tempPlayer.setBetBobo(tempPlayer.getBetBobo() + this.create.getDifen());
          GameStartStructrue gss = new GameStartStructrue();
          gss.setUid(tempPlayer.getUserId());
          if (mangguoFen > 0) {
            if ((this.mangguoType == 2 && this.zouMangUid != tempPlayer.getUserId()) || this.mangguoType == 1) {
              this.mangguochi += mangguoFen;
              tempPlayer.setUsebobo(tempPlayer.getUsebobo() - mangguoFen);
              gss.setMangguo(mangguoFen);
              LogManager.getInstance().Log(tempPlayer.getUserId() + " 开局扣芒果：" + mangguoFen + " tableid:" + getID());
            }
          }
          listGSS.add(gss);
        }
      }
      this.zouMangUid = 0;
      this.operateTime = 0;
      if (this.gameCurrNumber == 0) {
        int random = random(GetPlayerCount());
        ChexuanPlayer nextPlayer = nextPlayer(random);
        this.zhuangUid = nextPlayer.getUserId();
        this.zhuangSeatNo = nextPlayer.getSeatNo();
      } else {
        ChexuanPlayer nextPlayer = nextPlayer(this.zhuangSeatNo);
        this.zhuangUid = nextPlayer.getUserId();
        this.zhuangSeatNo = nextPlayer.getSeatNo();
      }
      this.maxBet = this.create.getDifen();
      GameStartRsp rsp = new GameStartRsp();
      rsp.setGss(listGSS.toArray(new GameStartStructrue[listGSS.size()]));
      rsp.setZhuangUid(this.zhuangUid);
      BroadCast(rsp, 2);
      this.gameStartMangguoStopTime = 0;
      if (mangguoFen > 0) {
        this.gameStartMangguoStopTime = 3;
      } else {
        licensing(false);
      }

    }
  }

  /**
   * 发牌
   *
   * @param zhifaBool 直发 二三轮
   */
  @SuppressWarnings("unchecked")
  private void licensing(boolean zhifaBool) {
    Set<Integer> clientIds = null;
    HashMap<Integer, RobotClient> clients = null;
    if (null != RobotManager.getTask()) {
      clients = (HashMap<Integer, RobotClient>) RobotManager.getTask().getClientMap();
      clientIds = clients.keySet();
      LogManager.getInstance().Log("机器人队列：" + clientIds);
    }
    if (this.chexuanStatus != ChexuanTableStatus.LICENSING || this.round == 3) {
      return;
    }
    this.round++;
    this.currRoundBetBool = false;
    if (this.round == 1) {
      this.gameCurrNumber++;
      ArrayList<PaperCard> listCheatCard = new ArrayList<PaperCard>();
      int cheatSeatNo = -1;
      for (AbstractPlayer abPlayer : getPlayers()) {
        ChexuanPlayer player = (ChexuanPlayer) abPlayer;

        if (player.isReady()) { // && player.getListCheatCard().size() == 4
          // 通过设置listCheatCard的值，可以指定某玩家的卡牌
          if (null != clientIds && clientIds.contains(player.getUserId())) {
            LogManager.getInstance().Log("该用户是机器人");
            RobotClient robot = clients.get(player.getUserId());
            int prop = robot.getGrateCardsProbability();
            LogManager.getInstance().Log("该机器人好牌概率: " + prop);
            if (prop > 0) {
              Random random = new Random(System.currentTimeMillis());
              int rand = random.nextInt(100);
              LogManager.getInstance().Log("随机到的数是: " + rand);
              if (rand < prop) {
                // TODO: 机器人作弊卡牌 随机好牌
                listCheatCard = (ArrayList<PaperCard>) GrateCardsVo.getInstance().getCards().getRandom();
                cheatSeatNo = player.getSeatNo();
                LogManager.getInstance().Log("机器人取牌，牌值：" + listCheatCard);
              }
            }
          }
          ArrayList<PaperCard> paperCards = WebServer.getZbMap().remove(player.getUserId());

          LogManager.getInstance().Log("发牌: uid=" + player.getUserId() + ", paperCards=" + paperCards);
          if (paperCards != null && paperCards.size() > 0) {
            LogManager.getInstance().Log("发牌重赋值");
            listCheatCard = paperCards;
            cheatSeatNo = player.getSeatNo();
            break;
          }
        }
      }
      LogManager.getInstance().Log("发牌: cheatSeatNo=" + cheatSeatNo + ", listCheatCard=" + listCheatCard);
      // 获取玩家后台设置的当前卡牌，
      this.paperCardLibrary = GameAlgorithm.initCardGroup(listCheatCard, cheatSeatNo);
      for (AbstractPlayer abPlayer : getPlayers()) {
        ChexuanPlayer player = (ChexuanPlayer) abPlayer;
        if (player.isReady()) {
          ArrayList<PaperCard> arrayList = this.paperCardLibrary.get(player.getSeatNo());
          player.getListHand().add(arrayList.get(0));
          player.getListHand().add(arrayList.get(1));
          ArrayList<LicensingStructure> listLS = new ArrayList<LicensingStructure>();
          LicensingStructure li = new LicensingStructure();
          li.setCards(player.paperCardToCardStructrue(player.getListHand()));
          li.setFabrandid(player.getUserId());
          listLS.add(li);
          LicensingRsp rsp = new LicensingRsp();
          rsp.setLun(this.round);
          rsp.setCards(listLS.toArray(new LicensingStructure[listLS.size()]));
          player.getClient().Send(rsp);
          player.getListCheatCard().clear();
        } else {
          LicensingRsp rsp = new LicensingRsp();
          rsp.setLun(this.round);
          rsp.setCards(null);
          player.getClient().Send(rsp);
        }
      }
      LicensingRsp rsp = new LicensingRsp();
      rsp.setLun(this.round);
      rsp.setCards(null);
      BroadCast(rsp, 1);
      firstOperation();
    } else if (this.round == 2) {
      ArrayList<LicensingStructure> listLS = new ArrayList<LicensingStructure>();
      for (AbstractPlayer abPlayer : getPlayers()) {
        ChexuanPlayer player = (ChexuanPlayer) abPlayer;
        if (player.isReady() && player.getOperateType() != 0) {
          if (player.getOperateType() != 2) {
            player.setOperateType(-1);
          }
          ArrayList<PaperCard> arrayList = this.paperCardLibrary.get(player.getSeatNo());
          LicensingStructure li = new LicensingStructure();
          if (zhifaBool) {
            player.getListHand().add(arrayList.get(2));
            player.getListHand().add(arrayList.get(3));
            List<PaperCard> subList = arrayList.subList(2, 4);
            li.setCards(player.paperCardToCardStructrue(subList));
          } else {
            player.getListHand().add(arrayList.get(2));
            List<PaperCard> subList = arrayList.subList(2, 3);
            li.setCards(player.paperCardToCardStructrue(subList));
          }
          li.setFabrandid(player.getUserId());
          listLS.add(li);
        }
      }
      LicensingRsp rsp = new LicensingRsp();
      rsp.setLun(this.round);
      rsp.setCards(listLS.toArray(new LicensingStructure[listLS.size()]));
      BroadCast(rsp, 2);
      if (zhifaBool) {
        if (checkPlayerCuopai()) {
          updateStatus(ChexuanTableStatus.CUOPAI);
          this.operateTime = 12;
          this.zhifaLicensingToGroupCardsBoolTime = 4;
        } else {
          this.zhifaLicensingToGroupCardsBoolTime = 2;
        }
        this.round = 3;
      } else {
        firstOperation();

      }
    } else if (this.round == 3) {
      ArrayList<LicensingStructure> listLS = new ArrayList<LicensingStructure>();
      for (AbstractPlayer abPlayer : getPlayers()) {
        ChexuanPlayer player = (ChexuanPlayer) abPlayer;
        if (player.isReady() && player.getOperateType() != 0) {
          if (player.getOperateType() != 2) {
            player.setOperateType(-1);
          }
          ArrayList<PaperCard> arrayList = this.paperCardLibrary.get(player.getSeatNo());
          player.getListHand().add(arrayList.get(3));
          List<PaperCard> subList = arrayList.subList(3, 4);
          LicensingStructure li = new LicensingStructure();
          li.setCards(player.paperCardToCardStructrue(subList));
          li.setFabrandid(player.getUserId());
          listLS.add(li);
        }
      }
      LicensingRsp rsp = new LicensingRsp();
      rsp.setLun(this.round);
      rsp.setCards(listLS.toArray(new LicensingStructure[listLS.size()]));
      BroadCast(rsp, 2);
      if (zhifaBool) {
        if (checkPlayerCuopai()) {
          updateStatus(ChexuanTableStatus.CUOPAI);
          this.operateTime = 12;
        }
        this.round = 3;
        this.zhifaLicensingToGroupCardsBoolTime = 2;
      } else {
        if (checkPlayerCuopai()) {
          updateStatus(ChexuanTableStatus.CUOPAI);
          this.operateTime = 12;
        } else {
          firstOperation();
        }
      }
    }
  }

  public void playerOperateCuopai(LogicClient client) {
    PlayerCuopaiNoticeRsp rsp = new PlayerCuopaiNoticeRsp();
    rsp.setIsok(1);
    ChexuanPlayer player = (ChexuanPlayer) getPlayer(client.getUserId());
    if (player != null && player.isCuopaiBool()) {
      player.setCuopaiTypeBool(true);
      rsp.setIsok(0);
      rsp.setUid(client.getUserId());
      BroadCast(rsp, 2);
      if (!checkPlayerCuopai() && this.operateTime > 1) {
        this.operateTime = 1;
//				noticeCuopaiEnd();
      }
    } else {
      client.Send(rsp);
    }
  }

  /**
   * 发完牌通知操作
   */
  private void firstOperation() {
    if (this.round == 1) {
      this.operateUid = nextPlayer(this.zhuangSeatNo).getUserId();
      this.licensingTime = 3;
    } else {
      ArrayList<Integer> listGameingUids = new ArrayList<Integer>();
      int nextSeatNo = this.zhuangSeatNo;
      for (int i = 0; i < this.create.getGamesPeopleCount(); i++) {
        int userId = nextPlayer(nextSeatNo).getUserId();
        if (!listGameingUids.contains(userId)) {
          listGameingUids.add(userId);
          ChexuanPlayer player = (ChexuanPlayer) getPlayer(userId);
          nextSeatNo = player.getSeatNo();
        }
      }
      this.operateUid = licensingFirstMaxCardPlayer(listGameingUids);
      this.licensingTime = 2;
//			if(this.round == 2) {
//				this.licensingTime = 2;
//			} else {
//				this.licensingTime = 1;
//			}

    }
    updateStatus(ChexuanTableStatus.BET);
  }

  /**
   * 2 3 轮找最大牌面操作
   */
  private int licensingFirstMaxCardPlayer(ArrayList<Integer> listUids) {
    Integer[] array = listUids.toArray(new Integer[listUids.size()]);
    for (int i = 0; i < array.length; i++) {
      for (int j = 0; j < array.length - 1 - i; j++) {
        ChexuanPlayer player_Front = (ChexuanPlayer) getPlayer(array[j]);
        ChexuanPlayer player_After = (ChexuanPlayer) getPlayer(array[j + 1]);
        PaperCard card_Front = null;
        PaperCard card_After = null;
        if (this.round == 2) {
          card_Front = player_Front.getListHand().get(2);
          card_After = player_After.getListHand().get(2);
        } else if (this.round == 3) {
          card_Front = player_Front.getListHand().get(3);
          card_After = player_After.getListHand().get(3);
        }
        if (card_Front != null && card_After != null) {
          if (card_Front.getChexuanValue() >= card_After.getChexuanValue()) {
            int tempUid = array[j];
            array[j] = array[j + 1];
            array[j + 1] = tempUid;
          }
        }
      }
    }
    return array[array.length - 1];
  }

  /**
   * 有人操作后 接下来的操作
   */
  private void checkNextOperate() {
    ChexuanPlayer player = (ChexuanPlayer) getPlayer(this.operateUid);
    if (player.getBetBobo() > this.maxBet) {
      this.maxBet = player.getBetBobo();
    }
    if (player.getOperateType() == 2 || player.getOperateType() == 3 || player.getOperateType() == 5) {
      this.currRoundBetBool = true;
    }
    int gameStartCount = 0;
    int xiuCount = 0;
    int diuCount = 0;
    int qiaoCount = 0;

    for (AbstractPlayer abPlayer : getPlayers()) {
      ChexuanPlayer tempPlayer = (ChexuanPlayer) abPlayer;
      if (tempPlayer.isReady()) {
        gameStartCount++;
        if (tempPlayer.getOperateType() == 0) {
          diuCount++;
        } else if (tempPlayer.getOperateType() == 1) {
          xiuCount++;
        } else if (tempPlayer.getOperateType() == 2) {
          qiaoCount++;
        }
      }
    }
    boolean nextBool = false;
    ChexuanPlayer nextPlayer = nextPlayer(player.getSeatNo());
    if (gameStartCount - diuCount > 1 && nextPlayer != null) {
      if (nextPlayer.getOperateType() == -1) {
        nextBool = true;
      } else if (nextPlayer.getUsebobo() > 0 && nextPlayer.getBetBobo() != this.maxBet) {
        nextBool = true;
      }
    }

    if (nextBool) {
      this.operateUid = nextPlayer.getUserId();
      broadcastCanOperation();
    } else {
      if (this.round == 3 || gameStartCount == xiuCount + diuCount || gameStartCount - diuCount == 1) {//结算 组牌
        NoticeGroupCard(gameStartCount == xiuCount + diuCount, gameStartCount - diuCount == 1);
      } else {
        boolean zhifaBool = false;
        if (gameStartCount == xiuCount + diuCount + qiaoCount || gameStartCount - diuCount - qiaoCount == 1) {
          zhifaBool = true;
        }
        updateStatus(ChexuanTableStatus.LICENSING);
        licensing(zhifaBool);
      }
    }
  }


  private void updateStatus(ChexuanTableStatus status) {
    this.chexuanStatus = status;

  }

  // 设置钵钵
  public void setUpBobo(LogicClient client, int bobo) {
    if (this.gameEnd) {
      return;
    }
    ChexuanPlayer player = (ChexuanPlayer) client.getPlayer();
    SetupboboRsp rsp = new SetupboboRsp();
    rsp.setIsOk((byte) 1);
    ChexuanStructrue struct = (ChexuanStructrue) this.create;
    int checkSetBoboValue = checkSetBoboValue(bobo);
    ///&& client.getVo().getIntegral() >= (bobo + checkSetBoboValue)
    if (bobo > 0 && bobo % struct.getDairumin() == 0) {
      //带入bobo 如果是俱乐部房间 判断一下玩家在俱乐部的信誉额度积分是否足够
      boolean nextflg = false;
      XyClubInfo xyClubInfo = DataManager.getInstance().getMapClub().get(client.getClubid());
      if (xyClubInfo != null) {
        //如果有俱乐部
        int backtype = xyClubInfo.intoTheBobo(bobo, this, client);

        if (backtype == 0) {
          nextflg = true;
        } else {
          rsp.setIsOk((byte) backtype);
        }
      } else {
        nextflg = true;
      }

      System.out.println("nextflg是"+nextflg);
      if (nextflg) {
        ChexuanStructrue cs = (ChexuanStructrue) this.create;
        if (cs.getControlBringIn() == 1) {
          addControlBringInRecord(client, bobo);
          rsp.setIsOk((byte) 0);
          client.Send(rsp);
        } else {
          determineSetBobo(player, bobo, checkSetBoboValue);
        }
      } else {
        client.Send(rsp);
      }
    } else {
      client.Send(rsp);
    }
  }

  private void addControlBringInRecord(LogicClient client, int bobo) {
    ControlBringInStruct cbi = new ControlBringInStruct();
    cbi.setHead(client.getVo().getNickName());
    cbi.setIntegral(bobo);
    cbi.setName(client.getVo().getNickName());
    cbi.setUid(client.getUserId());
    this.cbiId++;
    cbi.setId(this.cbiId);
    this.mapCBI.put(this.cbiId, cbi);
    ChexuanStructrue struct = (ChexuanStructrue) this.create;
    LogicPlayer clientPlayer = getClientPlayer(struct.getBankerid());
    if (clientPlayer != null) {
      GetControlBringInDataRsp grsp = new GetControlBringInDataRsp();
      Collection<ControlBringInStruct> values = this.mapCBI.values();
      grsp.setCbi(values.toArray(new ControlBringInStruct[values.size()]));
      clientPlayer.getClient().Send(grsp);
    }
  }

  private void gameToNextStart() {
    for (AbstractPlayer abPlayer : getPlayers()) {
      ChexuanPlayer tempPlayer = (ChexuanPlayer) abPlayer;
      if (tempPlayer.getNextLiuzuoTimeType() >= 0) {
        nextReservedSeat(tempPlayer);
      } else if (tempPlayer.getAutoOperateCount() >= 2 || tempPlayer.isNextStandUpBool()) {
        LogicClient client = (LogicClient) tempPlayer.getClient();
        standUp(client);
      }
//			else {
//				BroadcastSetupbobo bsb = new BroadcastSetupbobo();
//				bsb.setBobo(tempPlayer.getUsebobo());
//				bsb.setUid(tempPlayer.getUserId());
//				BroadCast(bsb, 2);
//			}
    }
    GameEndRsp rsp = new GameEndRsp();
    BroadCast(rsp, 2);
    bankerGameStart();
  }

  public void bankerGameStart() {
    if (this.gameEnd) {
      return;
    }
    if (this.chexuanStatus == ChexuanTableStatus.WAIT || (this.gameCurrNumber > 0 && this.chexuanStatus == ChexuanTableStatus.READ)) {
      if (this.chexuanStatus == ChexuanTableStatus.WAIT) {
        updateStatus(ChexuanTableStatus.READ);
        this.gameStartTime = System.currentTimeMillis();
      }
      ArrayList<Integer> listUid = new ArrayList<Integer>();
      for (AbstractPlayer abPlayer : getPlayers()) {
        ChexuanPlayer tempPlayer = (ChexuanPlayer) abPlayer;
        if (tempPlayer.getLiuZuoEndTime() == 0 && tempPlayer.getUsebobo() >= this.gameStartMinScore) {
          listUid.add(tempPlayer.getUserId());
        }
      }
      if (listUid.size() > 1 && this.gameReadyTime == 0 && this.gameEndToNextStartTime == 0) {
        for (Integer uid : listUid) {
          ChexuanPlayer tempPlayer = (ChexuanPlayer) getPlayer(uid);
          tempPlayer.setReady(true);
        }
        this.gameReadyTime = 2;
      }
    }
  }

  public synchronized void gameOperate(LogicClient client, int operate, int bobo) {
    if (this.chexuanStatus != ChexuanTableStatus.BET) {
      OperationRsp rsp = new OperationRsp();
      rsp.setIsOk((byte) 1);
      client.Send(rsp);
      return;
    }
    switch (operate) {
      case 0:
        operateDiu(client);
        break;
      case 1:
        operateXiu(client);
        break;
      case 2:
        operateQiao(client);
        break;
      case 3:
        operateDa(client, bobo);
        break;
      case 5:
        operateGen(client);
        break;
      default:
        OperationRsp rsp = new OperationRsp();
        rsp.setIsOk((byte) 2);
        client.Send(rsp);
        break;
    }
  }

  private void operateDiu(LogicClient client) {
    OperationRsp rsp = new OperationRsp();
    rsp.setIsOk((byte) 3);
    if (client.getUserId() == this.operateUid) {
      ChexuanPlayer player = (ChexuanPlayer) client.getPlayer();
      rsp.setIsOk((byte) 4);
      if (player.getOperateType() == -1) {
        player.setOperateType(0);
        player.setRound(this.round);
        rsp.setIsOk((byte) 0);
        client.Send(rsp);
        broadcastOperation(0, player.getOperateType());
        checkNextOperate();
      } else {
        client.Send(rsp);
      }
    } else {
      client.Send(rsp);
    }

  }

  private void operateXiu(LogicClient client) {
    OperationRsp rsp = new OperationRsp();
    rsp.setIsOk((byte) 3);
    if (client.getUserId() == this.operateUid && !this.currRoundBetBool) {
      ChexuanPlayer player = (ChexuanPlayer) client.getPlayer();
      rsp.setIsOk((byte) 4);
      if (player.getOperateType() == -1) {
        player.setOperateType(1);
        player.setRound(this.round);
        rsp.setIsOk((byte) 0);
        client.Send(rsp);
        broadcastOperation(0, player.getOperateType());
        checkNextOperate();
      } else {
        client.Send(rsp);
      }
    } else {
      client.Send(rsp);
    }

  }

  private void operateQiao(LogicClient client) {
    OperationRsp rsp = new OperationRsp();
    rsp.setIsOk((byte) 3);
    if (client.getUserId() == this.operateUid) {
      ChexuanPlayer player = (ChexuanPlayer) client.getPlayer();
      rsp.setIsOk((byte) 4);
      if (player.getOperateType() == -1) {
        player.setBetBobo(player.getBetBobo() + player.getUsebobo());
        player.setOperateType(2);
        player.setRound(this.round);
        rsp.setIsOk((byte) 0);
        client.Send(rsp);
        this.pichi += player.getUsebobo();
        broadcastOperation(player.getUsebobo(), player.getOperateType());
        player.setUsebobo(0);
        checkNextOperate();
      } else {
        client.Send(rsp);
      }
    } else {
      client.Send(rsp);
    }

  }

  private void operateDa(LogicClient client, int bobo) {
    OperationRsp rsp = new OperationRsp();
    rsp.setIsOk((byte) 3);
    if (client.getUserId() == this.operateUid) {
      ChexuanPlayer player = (ChexuanPlayer) client.getPlayer();
      rsp.setIsOk((byte) 4);
      int genScore = this.maxBet - player.getBetBobo();
      if (player != null && player.getOperateType() == -1 && player.getUsebobo() > bobo && bobo > genScore) {
        player.setBetBobo(player.getBetBobo() + bobo);
        player.setUsebobo(player.getUsebobo() - bobo);
        player.setOperateType(3);
        player.setRound(this.round);
        rsp.setIsOk((byte) 0);
        client.Send(rsp);
        this.pichi += bobo;
        broadcastOperation(bobo, player.getOperateType());
        checkNextOperate();
      } else {
        client.Send(rsp);
      }
    } else {
      client.Send(rsp);
    }

  }

  private void operateGen(LogicClient client) {
    OperationRsp rsp = new OperationRsp();
    rsp.setIsOk((byte) 3);
    if (client.getUserId() == this.operateUid) {
      ChexuanPlayer player = (ChexuanPlayer) client.getPlayer();
      rsp.setIsOk((byte) 4);
      int genScore = this.maxBet - player.getBetBobo();
      if (genScore > 0 && player != null && player.getOperateType() == -1 && player.getUsebobo() > genScore) {
        player.setBetBobo(player.getBetBobo() + genScore);
        player.setUsebobo(player.getUsebobo() - genScore);
        player.setOperateType(5);
        player.setRound(this.round);
        rsp.setIsOk((byte) 0);
        client.Send(rsp);
        this.pichi += genScore;
        broadcastOperation(genScore, player.getOperateType());
        checkNextOperate();
      } else {
        client.Send(rsp);
      }
    } else {
      client.Send(rsp);
    }
  }

  /**
   * @param mangguoBool
   * @param diuBool     丢完了 只有一个人
   */
  private void NoticeGroupCard(boolean mangguoBool, boolean diuBool) {
    if (this.chexuanStatus != ChexuanTableStatus.BET) {
      return;
    }
    updateStatus(ChexuanTableStatus.GROUPCARDS);
    this.mangguoType = 0;
    if (mangguoBool) {//直接结算
      settlement(true);
    } else {
      if (diuBool) {
        if (this.round == 1) {
          this.mangguoType = 2;
          int operateTyep = 0;
          for (AbstractPlayer abPlayer : getPlayers()) {
            ChexuanPlayer tempPlayer = (ChexuanPlayer) abPlayer;
            if (tempPlayer.isReady()) {
              if (tempPlayer.getOperateType() != 0) {
                operateTyep = tempPlayer.getOperateType();
                this.zouMangUid = tempPlayer.getUserId();
              }
            }
          }
          if (!this.currRoundBetBool) {
            if (operateTyep == 1) {
              this.mangguoType = 1;
              this.zouMangUid = 0;
            }
          }
        }
        settlement(false);
      } else {
        //通知组牌
        BroadcastZuPaiRsp rsp = new BroadcastZuPaiRsp();
        rsp.setId(0);
        BroadCast(rsp, 2);
        this.operateTime = 30;
      }

    }
  }

  private void autoGroupCards() {
    for (AbstractPlayer abPlayer : getPlayers()) {
      ChexuanPlayer player = (ChexuanPlayer) abPlayer;
      if (player.isReady() && player.getOperateType() != 0 && player.getListHand().size() == 4) {
        LogicClient client = (LogicClient) player.getClient();
        ArrayList<Integer> listFront = new ArrayList<Integer>();
        ArrayList<Integer> listAfter = new ArrayList<Integer>();
        for (int i = 0; i < 4; i++) {
          if (i < 2) {
            listFront.add(player.getListHand().get(i).getId());
          } else {
            listAfter.add(player.getListHand().get(i).getId());
          }
        }
        operateGroupCards(client, listFront, listAfter);
      }
    }
  }

  public synchronized void operateGroupCards(LogicClient client, List<Integer> listFront, List<Integer> listAfter) {
    if (this.chexuanStatus != ChexuanTableStatus.GROUPCARDS) {
      return;
    }
    ChexuanPlayer player = (ChexuanPlayer) client.getPlayer();
    ZuPaiRsp rsp = new ZuPaiRsp();
    rsp.setIsOk((byte) 1);
    if (player.isReady() && player.getOperateType() != 0 && player.getListGroupCard().size() == 0) {
      ArrayList<PaperCard> paperFront = player.idToGetPaperCard(listFront);
      ArrayList<PaperCard> paperAfter = player.idToGetPaperCard(listAfter);
      if (paperFront.size() == 2 && paperAfter.size() == 2) {
        boolean repeatBool = false;
        for (PaperCard paperCard : paperFront) {
          if (paperAfter.contains(paperCard)) { // 判断头牌、尾牌是否存在重复（校验三花特？）
            repeatBool = true;
          }
        }
        if (!repeatBool) {
          paperFront.addAll(paperAfter);
          ArrayList<PaperCard> checkDingerHuang = GameAlgorithm.checkDingerHuang(paperFront);
          if (checkDingerHuang.size() == 2) {
            player.getListGroupCard().addAll(checkDingerHuang);
            for (PaperCard paperCard : paperFront) {
              if (paperCard.getNum() != 3 && paperCard.getNum() != 15) {
                player.getListGroupCard().add(paperCard);
              }
            }
          } else {
            player.getListGroupCard().addAll(paperFront);
          }
          player.setOperateType(6);
          ArrayList<Integer> listZu = new ArrayList<Integer>();
          for (PaperCard pc : player.getListGroupCard()) {
            listZu.add(pc.getId());
          }
          rsp.setIsOk((byte) 0);
          rsp.setZucards(listZu.toArray(new Integer[listZu.size()]));
          client.Send(rsp);
          BroadcastZuPaiRsp brsp = new BroadcastZuPaiRsp();
          brsp.setId(client.getUserId());
          BroadCast(brsp, 2);
          int surplusCount = 0;
          for (AbstractPlayer abPlayer : getPlayers()) {
            ChexuanPlayer tempPlayer = (ChexuanPlayer) abPlayer;
            if (tempPlayer.isReady() && tempPlayer.getOperateType() != 0 && tempPlayer.getListGroupCard().size() == 0) {
              surplusCount++;
            }
          }
          if (surplusCount == 0) {
            this.operateTime = 0;
            settlement(false);
          }
        } else {
          client.Send(rsp);
        }
      } else {
        client.Send(rsp);
      }
    } else {
      client.Send(rsp);
    }

  }

  private synchronized void settlement(boolean mangguoBool) {
    if (this.chexuanStatus != ChexuanTableStatus.GROUPCARDS) {
      return;
    }
    updateStatus(ChexuanTableStatus.END);
    this.operateTime = 0;
    LogManager.getInstance().Log("结束有芒果：" + this.mangguochi + "  tableid:" + getID());
    ChexuanStructrue struct = (ChexuanStructrue) this.create;
    if (mangguoBool) {
      if (this.mangguochi > 0) {
        this.mangguoType = 1;
      }
    } else {
      //分头尾
      ArrayList<Integer> gameUid = new ArrayList<Integer>();
      for (AbstractPlayer abPlayer : getPlayers()) {
        ChexuanPlayer player = (ChexuanPlayer) abPlayer;
        if (player.isReady()) {
          if (player.getOperateType() != 0) {
            if (player.getListHand().size() == 4 && player.getListGroupCard().size() == 4) {
              ArrayList<PaperCard> splitHeadTail = GameAlgorithm.splitHeadTail(player.getListGroupCard(), struct.getDijiuwang() == 1);
              player.setListGroupCard(splitHeadTail);

            }
            int checkSanhua = GameAlgorithm.checkSanhua(player.getListHand());
            if (checkSanhua != 0) {
              player.setSanhuaBool(true);
            }
            if (!player.isSanhuaBool()) {
              gameUid.add(player.getUserId());
            }
          }
          player.setScoringBobo(player.getBetBobo());
          LogManager.getInstance().Log("uid:" + player.getUserId() + " 组牌:" + player.getListGroupCard().toString() + " bet:" + player.getBetBobo() + " tableid:" + getID());
        }
      }
      int copyMangguofen = this.mangguochi;
      Integer[] array = gameUid.toArray(new Integer[gameUid.size()]);
      ArrayList<ArrayList<Integer>> sortByCardType = sortByCardType(array);
      for (int i = 0; i < sortByCardType.size(); i++) {
        ArrayList<Integer> arrayList = sortByCardType.get(i);
        LogManager.getInstance().Log("当前吃分uids:" + arrayList.toString() + "  tableid:" + getID());
        if (arrayList.size() > 1) {
          pingjuCheckScore(arrayList);
          pingjuCheckMangguoScore(arrayList, i == 0, copyMangguofen);
        } else {
          singleCheckScore(arrayList);
          singleCheckMangguoScore(arrayList, i == 0, copyMangguofen);
        }
      }
      if (this.mangguochi > 0) {
        this.mangguoType = 1;
      }
    }
    ArrayList<GameReviewStructrue> listGRS = new ArrayList<GameReviewStructrue>();
    ArrayList<SettlementStructrue> listSS = new ArrayList<SettlementStructrue>();
    for (AbstractPlayer abPlayer : getPlayers()) {
      ChexuanPlayer tempPlayer = (ChexuanPlayer) abPlayer;
      if (tempPlayer.isReady()) {
        tempPlayer.setUsebobo(tempPlayer.getUsebobo() + tempPlayer.getBetBobo());
        int diff = tempPlayer.getUsebobo() - tempPlayer.getGameStartMoney();
        UsersDao.updateUidToUseBobo(tempPlayer.getUserId(), diff);
        SettlementStructrue ss = new SettlementStructrue();
        ss.setUid(tempPlayer.getUserId());
        ss.setWin(tempPlayer.getWin());
        ss.setRefundBobo(tempPlayer.getNextBobo());
        ss.setWinmangguo(tempPlayer.getWinMangguo());
        ss.setPcs(tempPlayer.paperCardToCardStructrue(tempPlayer.getListGroupCard().size() == 0 ? tempPlayer.getListHand() : tempPlayer.getListGroupCard()));
        listSS.add(ss);
        LogManager.getInstance().Log("uid:" + tempPlayer.getUserId() + "  win:" + tempPlayer.getWin() + " 可使用钵钵:" + tempPlayer.getUsebobo() + " tableid:" + getID());
        LogicClient clientTemp = (LogicClient) tempPlayer.getClient();
        GameReviewStructrue grs = new GameReviewStructrue();
        grs.setUid(tempPlayer.getUserId());
        grs.setBet(tempPlayer.getScoringBobo());
        if (tempPlayer.getListGroupCard().size() == 0) {
          grs.setCards(tempPlayer.paperCardToCardStructrue(tempPlayer.getListHand()));
        } else {
          grs.setCards(tempPlayer.paperCardToCardStructrue(tempPlayer.getListGroupCard()));
        }
        ArrayList<Integer> listFrontCardids = new ArrayList<Integer>();
        for (int i = 0; i < tempPlayer.getListHand().size(); i++) {
          listFrontCardids.add(tempPlayer.getListHand().get(i).getId());
        }
        grs.setFrontCardids(listFrontCardids.toArray(new Integer[listFrontCardids.size()]));
        grs.setHead(clientTemp.getVo().getHead());
        grs.setName(clientTemp.getVo().getNickName());
        grs.setOperate(tempPlayer.getOperateType());
        grs.setWin(tempPlayer.getWin());
        grs.setWinMangguo(tempPlayer.getWinMangguo());
        grs.setZhuangStatus(tempPlayer.getUserId() == this.zhuangUid ? 1 : 0);
        grs.setSanhua(tempPlayer.isSanhuaBool() ? 1 : 0);
        listGRS.add(grs);
        //手数 局数 翻牌数....
        clientTemp.getVo().resultStatistics(tempPlayer.getWin() > 0, tempPlayer.getListGroupCard().size() == 4);
        mapRecord.get(tempPlayer.getUserId()).setShoushu(mapRecord.get(tempPlayer.getUserId()).getShoushu() + 1);
      }
    }
    this.mapGameReview.put(this.gameCurrNumber, listGRS);
    this.mapGameReviewXiupaiUids.put(this.gameCurrNumber, new HashSet<Integer>());
    if (this.mangguoType == 0) {
      if (struct.getKaiqimangquan() == 1) {
        this.mangguoCount = 1;
      }
    } else {
      if (this.mangguoCount < struct.getShengmangbeishu()) {
        this.mangguoCount++;
      }
    }
    LogManager.getInstance().Log("结束有芒果还剩：" + this.mangguochi + "  tableid:" + getID());
    checkGameStartMinScore();
    SettlementRsp rsp = new SettlementRsp();
    rsp.setSs(listSS.toArray(new SettlementStructrue[listSS.size()]));
    rsp.setStartMinScore(this.gameStartMinScore);
    BroadCast(rsp, 2);
    gamelog();
    gameEndInit();
  }

  private ArrayList<ArrayList<Integer>> sortByCardType(Integer[] array) {
    ArrayList<ArrayList<Integer>> listSort = new ArrayList<ArrayList<Integer>>();//头尾平 在同一级
    ChexuanStructrue struct = (ChexuanStructrue) this.create;
    for (int i = 0; i < array.length; i++) {
      ChexuanPlayer player = (ChexuanPlayer) getPlayer(array[i]);
      for (int k = 0; k < array.length; k++) {
        ChexuanPlayer tempPlayer = (ChexuanPlayer) getPlayer(array[k]);
        if (player.getUserId() != tempPlayer.getUserId()) {
          int compareCardBig = GameAlgorithm.compareCardBig(player.getListGroupCard(), tempPlayer.getListGroupCard(), struct.getDijiuwang() == 1);
          if (compareCardBig == 5 || compareCardBig == 7 || compareCardBig == 8) {
            player.addMinUid(tempPlayer.getUserId());
          } else if (compareCardBig == 4) {
            player.addPingjuUid(tempPlayer.getUserId());
            tempPlayer.addPingjuUid(player.getUserId());
          }
        }
      }
    }
    for (int i = 0; i < array.length; i++) {
      for (int j = 0; j < array.length - 1 - i; j++) {
        int frontUid = array[j];
        int afterUid = array[j + 1];
        ChexuanPlayer frontPlayer = (ChexuanPlayer) getPlayer(frontUid);
        ChexuanPlayer afterPlayer = (ChexuanPlayer) getPlayer(afterUid);
        int compareCardBig = GameAlgorithm.compareCardBig(frontPlayer.getListGroupCard(), afterPlayer.getListGroupCard(), struct.getDijiuwang() == 1);
        if (compareCardBig == 2 || compareCardBig == 5 || compareCardBig == 7 || compareCardBig == 8) {
          int tempUid = frontUid;
          array[j] = afterUid;
          array[j + 1] = tempUid;
        }
      }
    }
    for (int i = array.length - 1; i >= 0; i--) {
      ChexuanPlayer player = (ChexuanPlayer) getPlayer(array[i]);
      ArrayList<Integer> listUids = new ArrayList<Integer>();
      listUids.add(array[i]);
      listUids.addAll(player.getComparePingjuUid());
      listSort.add(listUids);
      i -= player.getComparePingjuUid().size();
    }
    return listSort;
  }

  /**
   * 平局查分
   *
   * @param listUids
   */
  private void pingjuCheckScore(ArrayList<Integer> listUids) {

    int maxScore = 0;
    ArrayList<Integer> loseUids = new ArrayList<Integer>();
    ArrayList<Integer> copyListUids = new ArrayList<Integer>(listUids);//按压分排序
    Integer[] array = copyListUids.toArray(new Integer[listUids.size()]);
    for (int i = 0; i < array.length; i++) {
      for (int j = 0; j < array.length - 1 - i; j++) {
        ChexuanPlayer player_1 = (ChexuanPlayer) getPlayer(array[j]);
        ChexuanPlayer player_2 = (ChexuanPlayer) getPlayer(array[j + 1]);
        if (player_1.getScoringBobo() > player_2.getScoringBobo()) {
          int tempUid = array[j + 1];
          array[j + 1] = array[j];
          array[j] = tempUid;
        }
      }
    }
    for (Integer integer : copyListUids) {
      ChexuanPlayer player = (ChexuanPlayer) getPlayer(integer.intValue());
      if (player.getScoringBobo() > maxScore) {
        maxScore = player.getScoringBobo();
      }
      if (loseUids.size() == 0) {
        loseUids.addAll(player.getCompareMinUid());
      }
    }
    LogManager.getInstance().Log("平局 比小：" + loseUids.toString());
    for (AbstractPlayer abPlayer : getPlayers()) {
      ChexuanPlayer losePlayer = (ChexuanPlayer) abPlayer;
      if (losePlayer.isReady() && !losePlayer.isSanhuaBool() && (loseUids.contains(losePlayer.getUserId()) || (losePlayer.getOperateType() == 0))) {
        if (losePlayer.getMostLoseScore() < maxScore) {
          losePlayer.setMostLoseScore(maxScore);
          if (maxScore > losePlayer.getScoringBobo()) {
            losePlayer.setMostLoseScore(losePlayer.getScoringBobo());
          }
        }
        for (int i = 0; i < copyListUids.size(); i++) {
          ChexuanPlayer player = (ChexuanPlayer) getPlayer(copyListUids.get(i));
          int minScore = player.getScoringBobo();
          //还能拿来输
          int currStillAbleToScore = losePlayer.getMostLoseScore() - (losePlayer.getScoringBobo() - losePlayer.getBetBobo());
          if (currStillAbleToScore > 0) {
            ArrayList<Integer> winUids = new ArrayList<Integer>();
            for (int j = i; j < copyListUids.size(); j++) {
              winUids.add(copyListUids.get(j));
            }
            int minWinScore = minScore / winUids.size();
            if (currStillAbleToScore < minWinScore) {
              minWinScore = currStillAbleToScore / winUids.size();
            }
            deductScore(losePlayer, winUids, minWinScore, currStillAbleToScore);
          }
        }
      }
    }
  }

  /**
   * 单人查分
   *
   * @param listUids
   */
  private void singleCheckScore(ArrayList<Integer> listUids) {
    ChexuanPlayer player = (ChexuanPlayer) getPlayer(listUids.get(0));
    LogManager.getInstance().Log("uid:" + player.getUserId() + " 比小：" + player.getCompareMinUid().toString());
    for (AbstractPlayer abPlayer : getPlayers()) {
      ChexuanPlayer losePlayer = (ChexuanPlayer) abPlayer;
      if (losePlayer.isReady() && !losePlayer.isSanhuaBool() && (player.getCompareMinUid().contains(losePlayer.getUserId()) || (losePlayer.getOperateType() == 0))) {
        if (losePlayer.getMostLoseScore() < player.getScoringBobo()) {
          losePlayer.setMostLoseScore(player.getScoringBobo());
          if (player.getScoringBobo() > losePlayer.getScoringBobo()) {
            losePlayer.setMostLoseScore(losePlayer.getScoringBobo());
          }
        }
        //还能拿来输
        int currStillAbleToScore = losePlayer.getMostLoseScore() - (losePlayer.getScoringBobo() - losePlayer.getBetBobo());
        if (currStillAbleToScore > 0) {
          int minWinScore = currStillAbleToScore;
          if (player.getScoringBobo() < currStillAbleToScore) {
            minWinScore = player.getScoringBobo();
          }
          deductScore(losePlayer, listUids, minWinScore, currStillAbleToScore);
        }
      }
    }
  }

  /**
   * 平局查芒果分
   *
   * @param listUids
   * @param maxWinBool         是不是大赢家
   * @param actualMangguoScore 芒果这轮总有值
   */
  private void pingjuCheckMangguoScore(ArrayList<Integer> listUids, boolean maxWinBool, int actualMangguoScore) {
    int maxScore = 0;
    ArrayList<Integer> copyListUids = new ArrayList<Integer>(listUids);//按压分排序
    Integer[] array = copyListUids.toArray(new Integer[listUids.size()]);
    for (int i = 0; i < array.length; i++) {
      for (int j = 0; j < array.length - 1 - i; j++) {
        ChexuanPlayer player_1 = (ChexuanPlayer) getPlayer(array[j]);
        ChexuanPlayer player_2 = (ChexuanPlayer) getPlayer(array[j + 1]);
        if (player_1.getScoringBobo() > player_2.getScoringBobo()) {
          int tempUid = array[j + 1];
          array[j + 1] = array[j];
          array[j] = tempUid;
        }
      }
    }
    for (Integer integer : copyListUids) {
      ChexuanPlayer player = (ChexuanPlayer) getPlayer(integer.intValue());
      if (player.getScoringBobo() > maxScore) {
        maxScore = player.getScoringBobo();
      }
    }
    if (maxWinBool) {
      int mostLoseMangguoScore = maxScore;
      if (actualMangguoScore < maxScore) {
        mostLoseMangguoScore = actualMangguoScore;
      }
      for (int i = 0; i < copyListUids.size(); i++) {
        ChexuanPlayer player = (ChexuanPlayer) getPlayer(copyListUids.get(i));
        int minScore = player.getScoringBobo();
        //还能拿来输
        int currStillAbleToScore = mostLoseMangguoScore - (actualMangguoScore - this.mangguochi);
        if (currStillAbleToScore > 0) {
          ArrayList<Integer> winUids = new ArrayList<Integer>();
          for (int j = i; j < copyListUids.size(); j++) {
            winUids.add(copyListUids.get(j));
          }
          int minWinScore = minScore / winUids.size();
          if (currStillAbleToScore < minWinScore) {
            minWinScore = currStillAbleToScore / winUids.size();
          }
          deductMangguoScore(winUids, minWinScore, currStillAbleToScore);
        }
      }
    } else if (maxScore >= actualMangguoScore) {
      for (int i = 0; i < copyListUids.size(); i++) {
        ChexuanPlayer player = (ChexuanPlayer) getPlayer(copyListUids.get(i));
        int minScore = player.getScoringBobo();
        //还能拿来输
        int currStillAbleToScore = this.mangguochi;
        if (currStillAbleToScore > 0) {
          ArrayList<Integer> winUids = new ArrayList<Integer>();
          for (int j = i; j < copyListUids.size(); j++) {
            winUids.add(copyListUids.get(j));
          }
          int minWinScore = minScore / winUids.size();
          if (currStillAbleToScore < minWinScore) {
            minWinScore = currStillAbleToScore / winUids.size();
          }
          deductMangguoScore(winUids, minWinScore, currStillAbleToScore);
        }
      }
    }
  }

  /**
   * 单人查芒果分
   *
   * @param listUids
   */
  private void singleCheckMangguoScore(ArrayList<Integer> listUids, boolean maxWinBool, int actualMangguoScore) {
    ChexuanPlayer player = (ChexuanPlayer) getPlayer(listUids.get(0));
    if (maxWinBool) {
      //还能拿来输
      int currStillAbleToScore = this.mangguochi;
      if (this.mangguochi > player.getScoringBobo()) {
        currStillAbleToScore = player.getScoringBobo();
      }
      if (currStillAbleToScore > 0) {
        int minWinScore = currStillAbleToScore;
        if (player.getScoringBobo() < currStillAbleToScore) {
          minWinScore = player.getScoringBobo();
        }
        deductMangguoScore(listUids, minWinScore, currStillAbleToScore);
      }
    } else if (player.getScoringBobo() >= actualMangguoScore) {
      //还能拿来输
      int currStillAbleToScore = this.mangguochi;
      if (currStillAbleToScore > 0) {
        int minWinScore = currStillAbleToScore;
        if (player.getScoringBobo() < currStillAbleToScore) {
          minWinScore = player.getScoringBobo();
        }
        deductMangguoScore(listUids, minWinScore, currStillAbleToScore);
      }
    }
  }

  private void deductScore(ChexuanPlayer losePlayer, ArrayList<Integer> listUids, int score, int allScore) {
    int totalWin = 0;
    for (Integer integer : listUids) {
      ChexuanPlayer winPlayer = (ChexuanPlayer) getPlayer(integer.intValue());
      if (allScore >= score) {
        winPlayer.setUsebobo(score + winPlayer.getUsebobo());
        winPlayer.addWin(score);
        totalWin += score;
        allScore -= score;
        LogManager.getInstance().Log("uid:" + losePlayer.getUserId() + " 牌:" + losePlayer.getListGroupCard().toString() + " 被 uid:" + winPlayer.getUserId() + " 牌:" + winPlayer.getListGroupCard().toString() + " 吃分score:" + score + " tableid:" + getID());
      } else {
        winPlayer.setUsebobo(allScore + winPlayer.getUsebobo());
        winPlayer.addWin(allScore);
        totalWin += allScore;
        LogManager.getInstance().Log("uid:" + losePlayer.getUserId() + " 牌:" + losePlayer.getListGroupCard().toString() + " 被 uid:" + winPlayer.getUserId() + " 牌:" + winPlayer.getListGroupCard().toString() + " 吃分score:" + allScore + " tableid:" + getID());
        allScore = 0;
      }

    }
    losePlayer.setBetBobo(losePlayer.getBetBobo() - totalWin);
    losePlayer.addWin(-totalWin);
  }

  private void deductMangguoScore(ArrayList<Integer> listUids, int score, int allScore) {
    int totalWin = 0;
    for (Integer integer : listUids) {
      ChexuanPlayer winPlayer = (ChexuanPlayer) getPlayer(integer.intValue());
      if (allScore >= score) {
        winPlayer.setUsebobo(score + winPlayer.getUsebobo());
        winPlayer.addWin(score);
        winPlayer.setWinMangguo(winPlayer.getWinMangguo() + score);
        totalWin += score;
        allScore -= score;
        LogManager.getInstance().Log(" uid:" + winPlayer.getUserId() + " 吃芒分score:" + score + " tableid:" + getID());
      } else {
        winPlayer.setUsebobo(allScore + winPlayer.getUsebobo());
        winPlayer.addWin(allScore);
        winPlayer.setWinMangguo(winPlayer.getWinMangguo() + allScore);
        totalWin += allScore;
        LogManager.getInstance().Log(" uid:" + winPlayer.getUserId() + " 吃芒分score:" + allScore + " tableid:" + getID());
        allScore = 0;
      }
    }
    this.mangguochi -= totalWin;
  }

  private void gameEndInit() {
    if (this.chexuanStatus != ChexuanTableStatus.END) {
      return;
    }
    long diffTime = this.gameStartTime + (this.create.getGameallTime() * 60 * 1000) - System.currentTimeMillis();
    if (((int) diffTime / 1000) <= 0 || this.bankerCloseBool) {
      if (this.mangguochi == 0) {
        //this.gameEnd = true;
      }
    }
    for (AbstractPlayer abPlayer : getPlayers()) {
      ChexuanPlayer player = (ChexuanPlayer) abPlayer;
      if (player.isReady() || player.getNextBobo() > 0) {
        player.setUsebobo(player.getUsebobo() + player.getNextBobo());
        player.setNextBobo(0);
        realTimeRecord(player.getUserId(), null, 0, player.getUsebobo());
        player.init();
      }
      if (player.getUsebobo() < this.gameStartMinScore) {
        player.setSetBoboTime(System.currentTimeMillis());
      }
    }

    this.maxBet = 0;
    this.round = 0;
    this.pichi = 0;
    this.zhifaLicensingToGroupCardsBoolTime = 0;
    this.operateTime = 0;
    if (this.gameEnd) {
      tableClose();
    } else {
      this.gameEndToNextStartTime = 6;
      updateStatus(ChexuanTableStatus.READ);
    }
  }

  /**
   * 处理控制带入
   */
  public void operateControlBringIn(LogicClient client, int id, int type) {
    ControlBringInStruct cbi = this.getMapCBI().remove(id);
    ControlBringInRsp rsp = new ControlBringInRsp();
    rsp.setIsok(1);
    if (cbi != null) {
      if (type == 0) {
        rsp.setIsok(0);
        rsp.setId(id);
      } else {
        LogicPlayer clientPlayer = getClientPlayer(cbi.getUid());
        if (clientPlayer != null) {
          ChexuanPlayer tempPlayer = (ChexuanPlayer) clientPlayer;
          LogicClient tempClient = (LogicClient) tempPlayer.getClient();
          int checkSetBoboValue = checkSetBoboValue(cbi.getIntegral());
          if (tempClient.getVo().getIntegral() >= (cbi.getIntegral() + checkSetBoboValue)) {
            rsp.setId(id);
            rsp.setIsok(0);
            determineSetBobo(tempPlayer, cbi.getIntegral(), checkSetBoboValue);
          }
        }
      }

    }
    client.Send(rsp);
  }

  private void determineSetBobo(ChexuanPlayer player, int bobo, int serviceCharge) {

    LogicClient client = (LogicClient) player.getClient();
   //如果是俱乐部的牌局
    System.out.println("如果是俱乐部的牌局:"+client.getClubid());
    if(client.getClubid() == 0){
      client.getVo().AddIntegral(-(bobo + serviceCharge));
    }

    SetupboboRsp rsp = new SetupboboRsp();
    rsp.setBobo(bobo);
    rsp.setIsOk((byte) 0);
    client.Send(rsp);
    if (player.isReady()) {
      player.setNextBobo(player.getNextBobo() + bobo);
    } else {
      player.setUsebobo(player.getUsebobo() + bobo);
      BroadcastSetupbobo bsb = new BroadcastSetupbobo();
      bsb.setBobo(player.getUsebobo());
      bsb.setUid(client.getUserId());
      BroadCast(bsb, 2);
    }
    UsersDao.updateUidToUseBobo(client.getUserId(), bobo);
    client.getVo().Save();
    realTimeRecord(client.getUserId(), client.getVo().getNickName(), bobo, player.getUsebobo() + player.getNextBobo());
    player.setSetBoboTime(0);

    //如果选了满足人数就开始游戏则将游戏状态设置成准备状态
    if (this.create.getGamesPeopleCount() > 0 && this.chexuanStatus == ChexuanTableStatus.WAIT) {
      ArrayList<Integer> listUid = new ArrayList<Integer>();
      for (AbstractPlayer abPlayer : getPlayers()) {
        ChexuanPlayer tempPlayer = (ChexuanPlayer) abPlayer;
        if (tempPlayer.getLiuZuoEndTime() == 0 && tempPlayer.getUsebobo() >= this.gameStartMinScore) {
          listUid.add(tempPlayer.getUserId());
        }
      }
      ChexuanStructrue struct = (ChexuanStructrue) this.create;
      // 自动开始游戏
      if (struct.getAutoStartGameCount() != 0 && listUid.size() >= struct.getAutoStartGameCount()) {
        LogManager.getInstance().Log("满足人数，将游戏状态设置为准备状态" + struct.getAutoStartGameCount());
        updateStatus(ChexuanTableStatus.READ);
      }
    }

    if (this.chexuanStatus == ChexuanTableStatus.READ && this.gameReadyTime == 0 && this.gameEndToNextStartTime == 0) {
      ArrayList<Integer> listUid = new ArrayList<Integer>();
      for (AbstractPlayer abPlayer : getPlayers()) {
        ChexuanPlayer tempPlayer = (ChexuanPlayer) abPlayer;
        if (tempPlayer.getLiuZuoEndTime() == 0 && tempPlayer.getUsebobo() >= this.gameStartMinScore) {
          listUid.add(tempPlayer.getUserId());
        }
      }
      if (listUid.size() > 1) {
        for (Integer uid : listUid) {
          ChexuanPlayer tempPlayer = (ChexuanPlayer) getPlayer(uid);
          tempPlayer.setReady(true);
        }
        this.gameReadyTime = 2;
      }
    }


  }

  private void gamelog() {
    for (AbstractPlayer abPlayer : getPlayers()) {
      ChexuanPlayer player = (ChexuanPlayer) abPlayer;
      if (player.isReady()) {
        Gamelog log = new Gamelog();
        log.setRoomNumber(getID());
        log.setScore(player.getUsebobo() - player.getGameStartMoney());
        log.setUserid(player.getUserId());
        GamelogDao.insertInto(log);
      }
    }
  }

  private void gameOver() {
    ArrayList<RealTimeRecordStructrue> listRTRS = new ArrayList<RealTimeRecordStructrue>();
    for (Integer uid : this.mapRecord.keySet()) {
      GamePlayerInfo info = this.mapRecord.get(uid);
      System.out.println("gameOver==getTotalBobo=="+info.getTotalBobo());
      System.out.println("gameOve==getUseBobor=="+info.getUseBobo());
      RealTimeRecordStructrue rrs = new RealTimeRecordStructrue();
      rrs.setName(info.getName());
      rrs.setTotalBobo(info.getTotalBobo());
      rrs.setTotalWin(info.getUseBobo() - info.getTotalBobo());
      rrs.setUid(uid);
      listRTRS.add(rrs);
    }
    XyClubInfo xyClubInfo = DataManager.getInstance().getMapClub().get(this.clubid);
    String clubName = "";
    if (xyClubInfo != null) {
      clubName = xyClubInfo.getName();
    }
    for (AbstractPlayer abPlayer : getPlayers()) {
      ChexuanPlayer tempPlayer = (ChexuanPlayer) abPlayer;
      SummaryCalculationRsp rsp = new SummaryCalculationRsp();
      rsp.setRtrs(listRTRS.toArray(new RealTimeRecordStructrue[listRTRS.size()]));
      rsp.setClubName(clubName);
      System.out.println("j俱乐部==getUseBobor=="+tempPlayer.getUsebobo());
      rsp.setIntegral(tempPlayer.getUsebobo());
      int joinHandNumber = 0;
      for (Integer key : this.mapGameReview.keySet()) {
        ArrayList<GameReviewStructrue> arrayList = this.mapGameReview.get(key);
        for (GameReviewStructrue grs : arrayList) {
          if (grs.getUid().intValue() == tempPlayer.getUserId()) {
            joinHandNumber++;
            break;
          }
        }
      }
      rsp.setJoinHandNumber(joinHandNumber);
      rsp.setTotalHandNumber(this.mapGameReview.size());
      tempPlayer.getClient().Send(rsp);
    }
    for (AbstractPlayer abPlayer : this.watchWar.getPlayers()) {
      ChexuanPlayer tempPlayer = (ChexuanPlayer) abPlayer;
      SummaryCalculationRsp rsp = new SummaryCalculationRsp();
      rsp.setRtrs(listRTRS.toArray(new RealTimeRecordStructrue[listRTRS.size()]));
      rsp.setClubName(clubName);
      rsp.setIntegral(tempPlayer.getUsebobo());
      int joinHandNumber = 0;
      for (Integer key : this.mapGameReview.keySet()) {
        ArrayList<GameReviewStructrue> arrayList = this.mapGameReview.get(key);
        for (GameReviewStructrue grs : arrayList) {
          if (grs.getUid().intValue() == tempPlayer.getUserId()) {
            joinHandNumber++;
            break;
          }
        }
      }
      rsp.setJoinHandNumber(joinHandNumber);
      rsp.setTotalHandNumber(this.mapGameReview.size());
      tempPlayer.getClient().Send(rsp);
    }

  }

  private void realTimeRecord(int uid, String name, int bobo, int useBobo) {
    if (this.mapRecord.containsKey(uid)) {
      GamePlayerInfo rtrs = this.mapRecord.get(uid);
      rtrs.setTotalBobo(rtrs.getTotalBobo() + bobo);
      rtrs.setUseBobo(useBobo);
    } else {
      LogicClient client = (LogicClient) LogicServer.getInstance().getClient(uid);
      client.getVo().addZongjuCount();
      GamePlayerInfo rtrs = new GamePlayerInfo();
      rtrs.setName(name);
      rtrs.setTotalBobo(bobo);
      rtrs.setUseBobo(useBobo);
      rtrs.setClubid(client.getClubid());
      this.mapRecord.put(uid, rtrs);
    }
  }

  private ChexuanPlayer nextPlayer(int seatNo) {
    int nextSeatno = nextSeatno(seatNo);
    for (int i = 0; i < this.create.getGamesPeopleCount(); i++) {
      for (AbstractPlayer abPlayer : getPlayers()) {
        ChexuanPlayer player = (ChexuanPlayer) abPlayer;
        if (player.getSeatNo() == nextSeatno && player.isReady() && player.getOperateType() != 0 && player.getOperateType() != 2) {
          return player;
        }
      }
      nextSeatno = nextSeatno(nextSeatno);
    }
    return null;
  }

  /**
   * 通知到谁操作
   */
  private void broadcastCanOperation() {
    ChexuanPlayer player = (ChexuanPlayer) getPlayer(this.operateUid);
    player.setOperateType(-1);
    BroadcastCanOperationRsp rsp = new BroadcastCanOperationRsp();
    rsp.setUid(this.operateUid);
    BroadCast(rsp, 2);
    this.operateTime = 15;

    if (player.getListHand().size() > 2) {
      int checkSanhua = GameAlgorithm.checkSanhua(player.getListHand());
      if (checkSanhua != 0) {
        player.setSanhuaBool(true);
        LogicClient client = (LogicClient) player.getClient();
        gameOperate(client, 0, 0);
      }
    }

  }


  /**
   * 广播玩家操作
   */
  private void broadcastOperation(int bobo, int operate) {
    BroadcastOperationRsp rsp = new BroadcastOperationRsp();
    rsp.setChip(bobo);
    rsp.setOperation(operate);
    rsp.setUid(this.operateUid);
    BroadCast(rsp, 2);
  }

  private void noticeCuopaiStart() {
    if (this.chexuanStatus != ChexuanTableStatus.CUOPAI) {
      return;
    }
    NoticeCuopaiRsp nrsp = new NoticeCuopaiRsp();
    BroadCast(nrsp, 2);
  }

  private void noticeCuopaiEnd() {
    if (this.chexuanStatus != ChexuanTableStatus.CUOPAI) {
      return;
    }
    NoticeCuopaiEndRsp rsp = new NoticeCuopaiEndRsp();
    BroadCast(rsp, 2);
    if (this.zhifaLicensingToGroupCardsBoolTime > 0) {
      updateStatus(ChexuanTableStatus.BET);
      NoticeGroupCard(false, false);
    } else {
      firstOperation();
    }
  }

  public void checkGameStartMinScore() {
    this.gameStartMinScore = this.create.getDifen();
    ChexuanStructrue cs = (ChexuanStructrue) this.create;
    if (this.mangguoType == 0) {
      if (cs.getKaiqimangquan() == 1) {
        this.gameStartMinScore += this.create.getDifen() * 2;
      }
    } else {
      this.gameStartMinScore += this.create.getDifen() * 2 * this.mangguoCount;
    }
    this.gameStartMinScore += (16 * this.create.getDifen());
  }


  private boolean checkPlayerCuopai() {

    for (AbstractPlayer abPlayer : getPlayers()) {
      ChexuanPlayer palyer = (ChexuanPlayer) abPlayer;
      if (palyer.isReady() && palyer.isCuopaiBool() && palyer.getOperateType() != 0 && !palyer.isCuopaiTypeBool()) {
        return true;
      }
    }
    return false;
  }

  @Override
  public void enterWatchPlayer(LogicClient client) {

    LogManager.getInstance().Log("进入观战玩家client.getUserId():" + client.getUserId());
    ChexuanPlayer player = new ChexuanPlayer(client);
    LogManager.getInstance().Log("进入观战玩家" + player.toString());
    this.watchWar.addPlayer(player);
    GamePlayerInfo gamePlayerInfo = this.mapRecord.get(client.getUserId());
    if (gamePlayerInfo != null) {
      LogManager.getInstance().Log("进入观战玩家gamePlayerInfo:" + gamePlayerInfo.toString());
      player.setUsebobo(gamePlayerInfo.getUseBobo());
    }
  }

  @Override
  public void timeEvent() {

    if (this.gameEnd) {
      return;
    }

    if (this.gameReadyTime > 0 && this.gameEndToNextStartTime == 0) {
      this.gameReadyTime--;
      if (gameReadyTime == 0 && this.chexuanStatus == ChexuanTableStatus.READ) {
        //游戏开始
        gameStart();
      }
    }
    if (this.gameEndToNextStartTime > 0) {
      this.gameEndToNextStartTime--;
      if (this.gameEndToNextStartTime == 0) {
        gameToNextStart();
      }
    }
    if (this.operateTime > 0) {
      this.operateTime--;
      if (this.operateTime == 0) {
        if (this.chexuanStatus == ChexuanTableStatus.BET) {
          ChexuanPlayer player = (ChexuanPlayer) getPlayer(this.operateUid);
          player.setAutoOperateCount(player.getAutoOperateCount() + 1);
          LogicClient client = (LogicClient) player.getClient();
          gameOperate(client, this.currRoundBetBool ? 0 : 1, 0);
        } else if (this.chexuanStatus == ChexuanTableStatus.GROUPCARDS) {
          autoGroupCards();
        } else if (this.chexuanStatus == ChexuanTableStatus.CUOPAI) {
          noticeCuopaiEnd();
        }
      } else if (this.operateTime == 10 && this.chexuanStatus == ChexuanTableStatus.CUOPAI) {
        noticeCuopaiStart();
      }
    }
    if (this.gameStartMangguoStopTime > 0) {
      this.gameStartMangguoStopTime--;
      if (this.gameStartMangguoStopTime == 0) {
        licensing(false); // 发牌
      }
    }
    if (this.licensingTime > 0) {
      this.licensingTime--;
      if (this.licensingTime == 0) {
        broadcastCanOperation();
      }
    }
    if (this.chexuanStatus == ChexuanTableStatus.LICENSING && this.zhifaLicensingToGroupCardsBoolTime > 0) {
      this.zhifaLicensingToGroupCardsBoolTime--;
      if (this.zhifaLicensingToGroupCardsBoolTime == 0) {
        updateStatus(ChexuanTableStatus.BET);
        NoticeGroupCard(false, false);
      }
    }
    for (AbstractPlayer abPlayer : getPlayers()) {
      ChexuanPlayer player = (ChexuanPlayer) abPlayer;
      if (!player.isReady() && (player.getLiuZuoEndTime() > 0 || player.getSetBoboTime() > 0)) {
        int time = 10;
        if (player.getLiuZuoEndTime() > 0) {
          time = (int) ((player.getLiuZuoEndTime() / 1000) - (System.currentTimeMillis() / 1000));
        } else {
          time = (int) ((player.getSetBoboTime() / 1000) + 120 - (System.currentTimeMillis() / 1000));
        }
        if (time <= 0) {
          player.setLiuZuoEndTime(0);
          player.setSetBoboTime(0);
          LogicClient client = (LogicClient) player.getClient();
          standUp(client);
        }
      }
    }

    if (this.gameStartTime > 0) {
      long diffTime = this.gameStartTime + (this.create.getGameallTime() * 60 * 1000) - System.currentTimeMillis();
      if (((int) diffTime / 1000) <= 0 || this.bankerCloseBool) {
        if (this.chexuanStatus == ChexuanTableStatus.READ && this.gameReadyTime == 0) {
          if (this.mangguochi == 0) {
            this.gameEnd = true;
            this.chexuanStatus = ChexuanTableStatus.END;
            tableClose();
          }
        }
      }
    } else if (this.chexuanStatus == ChexuanTableStatus.WAIT && this.gameStartTime == 0) {
      long diffTime = System.currentTimeMillis() - this.tableCreateTime;
      if (((int) diffTime / 1000) >= 1800 || this.bankerCloseBool) {
        this.gameEnd = true;
        this.chexuanStatus = ChexuanTableStatus.END;
        tableClose();
      }
    }
  }


  @Override
  public void ready(LogicClient client) {


  }


  @Override
  public void toTableInfo(LogicClient client) {
    ChexuanStructrue struct = (ChexuanStructrue) this.create;
    RoomInfoRsp rsp = new RoomInfoRsp();
    rsp.setDifen(struct.getDifen());
    rsp.setDijiuwang(struct.getDijiuwang());
    rsp.setFanghuopai(struct.getFanghuopai());
    rsp.setGameallCount(struct.getGamesPeopleCount());
    rsp.setGameallTime(struct.getGameallTime());
    rsp.setGamechang(this.clubid);
    rsp.setGPSorIP(struct.getGPSorIP());
    rsp.setKaiqimangquan(struct.getKaiqimangquan());
    rsp.setRoomname(struct.getRoomname());
    rsp.setRoomNo(getID());
    rsp.setStatus(this.gameEnd ? -1 : (byte) this.chexuanStatus.getValue());
    rsp.setXiumangorzoumang(struct.getXiumangorzoumang());
    rsp.setHomeownerUid(struct.getBankerid());
    rsp.setShengmangbeishu(struct.getShengmangbeishu());
    rsp.setMangguochi(this.mangguochi);
    rsp.setPichi(this.pichi);
    rsp.setDairumin(struct.getDairumin());
    rsp.setOperateMaxScore(this.maxBet);
    rsp.setOperateUid(this.operateUid);
    rsp.setIsxiu(this.currRoundBetBool ? 0 : 1);
    rsp.setOperateSurplusTime(this.operateTime);
    rsp.setGameCurrNumber(this.gameCurrNumber);
    rsp.setZhuangUid(this.zhuangUid);
    rsp.setXiupaiMoney(Integer.parseInt(DataManager.getInstance().systemValue("xiupaimoney")));
    rsp.setStartMinScore(this.gameStartMinScore);
    rsp.setControlBringIn(struct.getControlBringIn());
    rsp.setBankerPower(checkBankerPower(client.getUserId()));
    rsp.setForbidChat(this.forbidChat ? 1 : 0);
    rsp.setFreeSeat(this.listFreeSeat.contains(client.getUserId()) ? 0 : 1);
    ArrayList<PlayerInfo> listPInfo = new ArrayList<PlayerInfo>();
    for (AbstractPlayer abPlayer : getPlayers()) {
      ChexuanPlayer tempPlayer = (ChexuanPlayer) abPlayer;
      PlayerInfo playerInfo = tempPlayer.toPlayerInfo(client.getUserId());
      listPInfo.add(playerInfo);
    }
    rsp.setPlayers(listPInfo.toArray(new PlayerInfo[listPInfo.size()]));
    rsp.setGameSurplusTime(struct.getGameallTime() * 60);
    if (this.chexuanStatus != ChexuanTableStatus.WAIT) {
      long diffTime = this.gameStartTime + (struct.getGameallTime() * 60 * 1000) - System.currentTimeMillis();
      rsp.setGameSurplusTime(0);
      if (diffTime / 1000 > 0) {
        rsp.setGameSurplusTime((int) (diffTime / 1000));
      }
    } else {
      long diffTime = System.currentTimeMillis() - this.tableCreateTime;
      rsp.setTableNoStartCloseTime(1800 - ((int) diffTime / 1000));
    }
    client.Send(rsp);
  }


  @Override
  public void otherEnter(LogicPlayer player) {
    OtherEnterRsp rsp = new OtherEnterRsp();
    rsp.setPlayer(player.toPlayerInfo(player.getUserId()));
    BroadCast(rsp, 2);
  }


  @Override
  public boolean leave(LogicClient client) {
    LogicPlayer clientPlayer = getClientPlayer(client.getUserId());
    if ((clientPlayer != null && !clientPlayer.isReady()) || this.gameEnd) {
      removePlayer(client.getUserId());
      this.getWatchWar().removePlayer(client.getUserId());
      client.setTableid(0);
      client.setRoomid(0);
      LeaveRsp rsp = new LeaveRsp();
      rsp.setIsOK((byte) 0);
      client.Send(rsp);
      OtherLeaveRoom oRsp = new OtherLeaveRoom();
      oRsp.setUid(client.getUserId());
      BroadCast(oRsp, 2);
      if (GetPlayerCount() == 0 && this.mangguochi > 0) {
        client.getVo().AddIntegral(this.mangguochi);
        this.mangguochi = 0;
      }
      if (this.gameEnd) {
        GamePlayerInfo gamePlayerInfo = this.mapRecord.get(client.getUserId());
        if (gamePlayerInfo != null) {
          int retIntegral = 0;
          if (gamePlayerInfo.getShoushu() > 0) {
            int win = gamePlayerInfo.getUseBobo() - gamePlayerInfo.getTotalBobo();
            if (win > 0) {
              int winbobo = win - gamePlayerInfo.getTotalBobo();
              //赢家返还积分的比例
              double winnerreturnAIntegral = Double.parseDouble(CompuUtils.divide(DataManager.getInstance().systemValue("winnerreturnAIntegral"), 100 + "").toString());
              BigDecimal winboboHalf = CompuUtils.multiply(winbobo, winnerreturnAIntegral);
              double floor = Math.floor(Double.valueOf(winboboHalf.toString()));
              retIntegral = (int) floor + gamePlayerInfo.getTotalBobo();
              System.out.println("赢家返还积分的比例："+retIntegral);
            } else {
              retIntegral = gamePlayerInfo.getUseBobo();
            }
          } else {
            retIntegral = gamePlayerInfo.getUseBobo();
          }
          System.out.println("哇哇哇哇哇哇哇："+retIntegral);
          System.out.println("22222哇哇哇哇哇哇哇："+gamePlayerInfo.getUseBobo());
          client.getVo().AddIntegral(retIntegral);
          UsersDao.updateUidToUseBobo(client.getUserId(), -gamePlayerInfo.getUseBobo());
          client.getVo().Save();
        }
      }
      return true;
    }
    return false;
  }


  @Override
  public void tableClose() {

    if (this.chexuanStatus != ChexuanTableStatus.END) {
      return;
    }
    this.gameEnd = true;
    gameEndSendClubData();
    gameOver();
    System.out.println("难道不让解getPlayers：" + getPlayers());
    for (AbstractPlayer abPlayer : getPlayers()) {
      ChexuanPlayer player = (ChexuanPlayer) abPlayer;
      LogicClient client = (LogicClient) player.getClient();
      leave(client);
      if (client.isLost()) {
        client.Close();
      }
      this.mapRecord.remove(client.getUserId());
    }
    System.out.println("难道不让解this.getWatchWar().getPlayers()：" + this.getWatchWar().getPlayers());
    for (AbstractPlayer abPlayer : this.getWatchWar().getPlayers()) {
      ChexuanPlayer player = (ChexuanPlayer) abPlayer;
      LogicClient client = (LogicClient) player.getClient();
      leave(client);
      if (client.isLost()) {
        client.Close();
      }
      this.mapRecord.remove(client.getUserId());
    }
    for (Integer uid : this.mapRecord.keySet()) {
      LogicClient client = (LogicClient) LogicServer.getInstance().getClient(uid);
      GamePlayerInfo gamePlayerInfo = this.mapRecord.get(uid);
      System.out.println("游戏结束"+gamePlayerInfo.getUseBobo());
      UsersDao.updateUidToUseBobo(uid, -gamePlayerInfo.getUseBobo());
      if (client != null) {
        if(client.getClubid() == 0){ //没有加入俱乐部返回钻石
          client.getVo().AddIntegral(gamePlayerInfo.getUseBobo());
          client.getVo().Save();
        }

      } else {
        UserVo.updateGlod(uid, gamePlayerInfo.getUseBobo(), 3);
      }
    }
    System.out.println("房间状态gettype()：" + gettype());
    AbstractRoom room = LogicServer.getInstance().getRoom(gettype() - 1);
    room.removeTable(this);
  }
}
